#include "tcpserver.hpp"
#include "protocol.hpp"
#include <memory>
#include "Daemon.hpp"
using namespace ns_tcpserver;

// 在这个文件里做计算

static void Usage(const std::string &proc)
{
    std::cout << "\nUsage:" << proc << "port" << std::endl;
}

// 最好加上静态，其他文件访问不到
static Response calculatorHelper(const Request &req)
{
    Response res(0, 0); // 初始化一下准备返回的值
    switch (req._op)
    {
    case '+':
        res._res = req._x + req._y;
        break;
    case '-':
        res._res = req._x - req._y;
        break;
    case '*':
        res._res = req._x * req._y;
        break;
    case '/':
        if (req._x == 0)
            res._code = 1;
        else
            res._res = req._x / req._y;
        break;
    case '%':
        if (req._x == 0)
            res._code = 2;
        else
            res._res = req._x % req._y;
        break;
    default:
        res._code = 3;
    }
    return res;
}

// 准确来说主要是在这里面进行通信
void calculator(int sock)
{
    while (1)
    {
        //如果客户端关闭，则会返回空串，就不用再继续了
        //防止发送后出错，服务端直接退出

        //1.获取信息 length/r/n_x _op _y/r/n
        std::string inbuffer;
        bool flag = Recv(sock,&inbuffer);
        if(!flag)
            break;
        //2.解码并计算
        std::string message = Decode(inbuffer);

        //3.反序列化  ->  将string写入结构体
        Request req;
        req.Deserialize(message); // 反序列化后里面有值了

        //4.业务逻辑
        Response rep = calculatorHelper(req);
        
        //5.序列化，变成字符串以进行发送
        std::string respStr = rep.Serialize(); // 序列化变成字符串

        //6.加码，添加上length
        std::string res = Encode(respStr);

        //7.发送消息
        Send(sock, res);
    }
}

int main(int args, char *argv[])
{
    if (args != 2)
    {
        Usage(argv[0]);
        exit(-1);
    }
    Mydaemon();
    uint16_t port = atoi(argv[1]);
    std::unique_ptr<TcpServer> server(new TcpServer(port));
    server->BindFunc(calculator);
    server->Start();
}